package xyz.mimai.media.netty.tcp.bad;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.CharsetUtil;

import java.util.concurrent.atomic.AtomicInteger;

public class Server {
    public static void main(String[] args) {
        //创建主线程组，只处理连接请求
        EventLoopGroup eventBossGroup = new NioEventLoopGroup(2) ;
        //创建工作线，接收主线程分发过来的任务，完成实际的工作                                                                                                                   程组
        EventLoopGroup eventWorkGroup = new NioEventLoopGroup(8) ;

        //创建一个服务器端的启动对象
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        //设置服务器的配置
        serverBootstrap.group(eventBossGroup,eventWorkGroup)
                .channel(NioServerSocketChannel.class)
                //ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数，
                //服务端处理客户端连接请求是顺序处理的，同一时间只能处理一个客户端连接，
                //多个客户端来的时候，服务端将不能处理的客户端连接请求放在队列中等待处理，backlog参数指定了队列的大小
                .option(ChannelOption.SO_BACKLOG,128)
                //Channeloption.SO_KEEPALIVE参数对应于套接字选项中的SO_KEEPALIVE，该参数用于设置TCP连接。
                //当设置该选项以后，如果在两小时内没有数据的通信时，TCP会自动发送一个活动探测数据报文。
                .childOption(ChannelOption.SO_KEEPALIVE,true)
                .childHandler(new ChannelInitializer<SocketChannel>() {  //为eventWorkGroup相关联的管道（pipeline）设置处理器

                    //指定业务处理的自定义handler
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new SelfDefineServerHandler());
                    }
                });

        try {
            ChannelFuture channelFuture = serverBootstrap.bind(7777).sync();
            channelFuture.channel().closeFuture().sync();
        }catch (InterruptedException ine){
            ine.printStackTrace();
        }finally {
            eventBossGroup.shutdownGracefully();
            eventWorkGroup.shutdownGracefully();
        }

    }

    public static class SelfDefineServerHandler extends SimpleChannelInboundHandler<ByteBuf>{

        private AtomicInteger count=new AtomicInteger(1);

        @Override
        public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
            int curCount =count.get();
            String recvContent  = msg.toString( CharsetUtil.UTF_8);
            System.out.println("第"+count.getAndAdd(1)+"次接收到Client消息，内容："+recvContent);
            String reply = "reply:第"+curCount+"个数据包\t";
            ByteBuf byteBuf= Unpooled.copiedBuffer(reply, CharsetUtil.UTF_8);
            ctx.writeAndFlush(byteBuf);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
       //     super.exceptionCaught(ctx, cause);
            System.out.println("发生了异常... ...");
            cause.printStackTrace();
            ctx.close();
        }
    }
}
